﻿using System;
using System.Linq;

namespace Shell.PocoDot.Configurations
{
    /// <summary>
    /// PocoDot 注册处的扩展类
    /// </summary>
    public static class IPocoDotRegistrarExtensions
    {
        /// <summary>
        /// 注册一个指定的 PocoDot 
        /// </summary>
        /// <typeparam name="TPocoDot">指定的 PocoDot 的类型</typeparam>
        /// <param name="configurator">PocoDot 注册处的实例</param>
        /// <param name="provider">与该 PocoDot 对应的持久层提供器的配置信息</param>
        /// <exception cref="System.ArgumentNullException">参数为空引用</exception>
        public static void Register<TPocoDot>(this IPocoDotRegistrar configurator, ProviderConfiguration provider)
            where TPocoDot : PocoDotBase
        {
            if (configurator == null)
            {
                throw new ArgumentNullException("configurator");
            }
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }
            configurator.Register(new PocoDotConfiguration(provider, typeof(TPocoDot)));
        }

        /// <summary>
        /// 获取指定的 PocoDot 的配置信息
        /// </summary>
        /// <typeparam name="TPocoDot">指定的 PocoDot 的类型</typeparam>
        /// <param name="configurator">PocoDot 注册处的实例</param>
        /// <returns>该指定的 PocoDot 的配置信息</returns>
        /// <exception cref="System.InvalidOperationException">不存在任何已注册的配置信息与此特定的 PocoDot 对应</exception>
        /// <exception cref="System.InvalidOperationException">存在大于一个已注册的配置信息与此特定的 PocoDot 对应</exception>
        public static PocoDotConfiguration Get<TPocoDot>(this IPocoDotRegistrar configurator)
            where TPocoDot : PocoDotBase
        {
            return configurator.Get(typeof(TPocoDot));
        }

        /// <summary>
        /// 获取指定的 PocoDot 的配置信息
        /// </summary>
        /// <param name="configurator">PocoDot 注册处的实例</param>
        /// <param name="pocoDotType">指定的 PocoDot 的类型</param>
        /// <returns>该指定的 PocoDot 的配置信息</returns>
        /// <exception cref="System.InvalidOperationException">不存在任何已注册的配置信息与此特定的 PocoDot 对应</exception>
        /// <exception cref="System.InvalidOperationException">存在大于一个已注册的配置信息与此特定的 PocoDot 对应</exception>
        public static PocoDotConfiguration Get(this IPocoDotRegistrar configurator, Type pocoDotType)
        {
            var configs = PocoDotRegistrar.Registrar.Configurations.Where(c => c.PocoDot == pocoDotType);
            var count = configs.Count();
            if (count == 0)
            {
                throw new InvalidOperationException(SR.Get("Error.PocoConfigurationNotExist", pocoDotType.Name));
            }
            if (count > 1)
            {
                throw new InvalidOperationException(SR.Get("Error.MorePocoConfigurationExists", pocoDotType.Name));
            }
            return configs.Single();
        }
    }
}
